package com.yyfax.ph.personal.update;

import android.Manifest;
import android.app.Activity;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import com.tbruyelle.rxpermissions.RxPermissions;
import com.yyfax.common.tools.PermissionUtil;
import com.yyfax.common.tools.Toaster;
import com.yyfax.ph.R;
import com.yyfax.ph.base.YJPH;
import com.yyfax.ph.common.utils.preferenceutils.PreferenceConstants;
import rx.functions.Action1;

import java.io.File;

public class UpdateService {
	private static final String TAG = UpdateService.class.getSimpleName();
	private static final String MIME_TYPE = "application/vnd.android.package-archive";
	// 下载到本地的apk文件名
	private static final String DOWNLOAD_APK_FILE_NAME = "CMA.apk";
	// 7.0及以上访问目录的权限, 值为AndroidManifest 的Provider中配置的android:authorities.
	private static final String PROVIDER_FILE_AUTHORITY = "com.yyfax.ph.fileprovider";

	private static long sReferenceId = -1;
	private static boolean sIsDownloading = false;

	private AlertDialog mAlertDialog;

	public UpdateService() {

	}

	private static long getReferenceId() {
		return sReferenceId;
	}

	private static void setReferenceId(long referenceId) {
		UpdateService.sReferenceId = referenceId;
	}

	/**
	 * 间隔一天再自动检测更新:
	 * 仅在自动更新检测的时候需要做下面的判断; 手动检测更新不用做此判断, 直接更新即可.
	 *
	 * @return true, 需要请求更新; false, 不满一天, 不需要请求更新.
	 */
	public static boolean isNeedCheckUpdate() {
		boolean needCheckUpdate = true;
		long lastCancelTime = YJPH.getInstance().getPreferenceManager().getLastCancelUpdateTime((long) 0);
		long currentTime = System.currentTimeMillis();
		long interval = (currentTime - lastCancelTime) / 1000;
		boolean show = interval >= 60 * 60 * 24;//一天
		if (!show) {
			needCheckUpdate = false;
		}

		return needCheckUpdate;
	}

	public AlertDialog showUpdateDialog(final Context context, final boolean forceUpdate, @NonNull final String apkUrl, final String updateDescription, final String title) {
		if (mAlertDialog != null && mAlertDialog.isShowing()) {
			return mAlertDialog;
		}

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setTitle(title);
		builder.setMessage(updateDescription);
		if (forceUpdate) {
			// 退出应用
			builder.setPositiveButton(context.getResources().getString(R.string.kill_app),
					new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialogInterface, int arg1) {
							((Activity) (context)).finish();
						}
					}
			);
		} else {
			// TODO: 2017/5/3  这个监听似乎没用到???
			builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
				@Override
				public void onCancel(DialogInterface dialogInterface) {
					long currentTime = System.currentTimeMillis();
					YJPH.getInstance().getPreferenceManager()
							.savePreference(PreferenceConstants.SP_KEY_LAST_CANCEL_UPDATE_TIME_FLAG, currentTime);
				}
			});
			// 稍后提醒
			builder.setPositiveButton(context.getResources().getString(R.string.remind_later),
					new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialogInterface, int arg1) {
							long currentTime = System.currentTimeMillis();
							YJPH.getInstance().getPreferenceManager()
									.savePreference(PreferenceConstants.SP_KEY_LAST_CANCEL_UPDATE_TIME_FLAG, currentTime);
						}
					}
			);

		}

		// 立即更新,这里不做点击监听, 放到show之后去监听.
		builder.setNegativeButton(context.getResources().getString(R.string.update_now),null);

		mAlertDialog = builder.create();
		mAlertDialog.setCanceledOnTouchOutside(false);
		mAlertDialog.setCancelable(false);
		mAlertDialog.show();

		// 作用:点击按钮dialog不消失, 以下监听必须在show方法之后
		mAlertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// 防止同时下载.
				if (sIsDownloading) {
					return;
				}

				// 判断是否有SD卡权限.
				if (!PermissionUtil.isSdkUnderM() && !PermissionUtil.checkAppPermission(context
						, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
					RxPermissions rxPermissions = new RxPermissions((Activity) context);
					rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
							.subscribe(new Action1<Boolean>() {
								@Override
								public void call(Boolean granted) {
									if(granted){ // 在android 6.0之前会默认返回true
										// 权限请求成功
										downLoadAPK(context, apkUrl);
									} else {
										sIsDownloading = false;
										// 权限请求失败
										Toast.makeText(context, R.string.write_storage_permission_hint, Toast.LENGTH_SHORT).show();
									}
								}
							});
					return;
				}

				downLoadAPK(context, apkUrl);
				// 非强制更新,点击立即更新后, 关闭更新弹框.
			}
		});

		return mAlertDialog;
	}

	private void downLoadAPK(Context context, String url) {
		if (TextUtils.isEmpty(url)) {
			return;
		}

		try {
			PackageManager pm = context.getApplicationContext().getPackageManager();
			String appName = context.getApplicationContext().getApplicationInfo().loadLabel(pm).toString();

			// 删除历史下载.
			File file = new File(Environment.getExternalStoragePublicDirectory(
					Environment.DIRECTORY_DOWNLOADS) + File.separator + DOWNLOAD_APK_FILE_NAME);
			if (file.isFile() && file.exists()) {
				file.delete();
			}

			Uri uri = Uri.parse(url);
			DownloadManager.Request request = new DownloadManager.Request(uri);
			request.allowScanningByMediaScanner();
			request.setVisibleInDownloadsUi(true);//设置下载中显示Notification
			request.setMimeType(MIME_TYPE);
			request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, DOWNLOAD_APK_FILE_NAME);
			request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
			request.setTitle(appName);

			final DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
			long reference = dm.enqueue(request);

			setReferenceId(reference);
			sIsDownloading = true;
		} catch (Exception exception) {
			Toaster.showShortToast(context, "更新失败");
		}
	}

	public void closeDialog() {
		if (null != mAlertDialog && mAlertDialog.isShowing()) {
			mAlertDialog.dismiss();
			mAlertDialog = null;
		}
	}

	public static class UpdateBroadcastReceiver extends BroadcastReceiver {
		public UpdateBroadcastReceiver() {
		}

		@Override
		public void onReceive(Context context, Intent intent) {
			sIsDownloading = false;
			long myDownloadID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
			long referenceID = getReferenceId();
			if (myDownloadID != -1 && referenceID != myDownloadID) {
				return;
			}

			installAPK(context);
		}

		private void installAPK(Context context) {
			File file = new File(Environment.getExternalStoragePublicDirectory(
					Environment.DIRECTORY_DOWNLOADS), DOWNLOAD_APK_FILE_NAME);
			Intent intent = new Intent(Intent.ACTION_VIEW);
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			if (Build.VERSION.SDK_INT >= 24) {
				//参数1,上下文; 参数2,Provider主机地址(和配置文件中保持一致); 参数3,共享的文件.
				Uri apkUri = FileProvider.getUriForFile(context, PROVIDER_FILE_AUTHORITY, file);
				// 授权访问该Uri所代表的文件
				intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
				intent.setDataAndType(apkUri, MIME_TYPE);
			} else {
				intent.setDataAndType(Uri.fromFile(file), MIME_TYPE);
			}
			context.startActivity(intent);
		}
	}
}
